from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField, TextAreaField
from wtforms.validators import DataRequired, Email, EqualTo, ValidationError, Length

# 3.2, login form
from app.models import User

from flask_babel import lazy_gettext as _l  # 13.2 导入替换翻译函数并重命名


class LoginForm(FlaskForm):
# StringField, PasswordField, BooleanField, SubmitField classes are imported directly from the WTForms package
# Each field is given a description or label as a first argument.
# validators argument  is used to attach validation behaviors to fields.
    username = StringField(_l('Username'), validators=[DataRequired()])   # 13.2 from flask_babel import lazy_gettext as _l
    password = PasswordField(_l('Password'), validators=[DataRequired()])
    remember_me = BooleanField(_l('Remember Me'))
    submit = SubmitField(_l('Sign In'))


# 5.9 User registration form
# validator--emal, equalto
# custom validator--make sure that the username and email address entered by the user are not already in the database
# wtforms.validators.ValidationError--Raised when a validator fails to validate its input.
class RegistrationForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired()])
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    password2 = PasswordField(
        'Repeat Password', validators=[DataRequired(), EqualTo('password')])
    submit = SubmitField('Register')

    def validate_username(self, username):
        user = User.query.filter_by(username=username.data).first()
        if user is not None:
            raise ValidationError('Please use a different username.')

    def validate_email(self, email):
        user = User.query.filter_by(email=email.data).first()
        if user is not None:
            raise ValidationError('Please use a different email address.')

# 6.6 profile editor form class
# new field type--TextAreaField, new validator--Length
class EditProfileForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired()])
    about_me = TextAreaField('About me', validators=[Length(min=0, max=140)])
    submit = SubmitField('Submit')
# 7.6 implement the username validation
# 1. an overloaded constructor that accepts the original username as an argument
#  This username is saved as an instance variable, and checked in the validate_username() method.
    def __init__(self, original_username, *args, **kwargs):
        super(EditProfileForm, self).__init__(*args, **kwargs)
        self.original_username = original_username

    def validate_username(self, username):
        if username.data != self.original_username:
            user = User.query.filter_by(username=self.username.data).first()
            if user is not None:
                raise ValidationError('Please use a different username.')
# 8.8 Empty form for following and unfollowing
class EmptyForm(FlaskForm):
    submit = SubmitField('Submit')

# 9.1 blog submission form
class PostForm(FlaskForm):
    post = TextAreaField('Say something', validators=[
        DataRequired(), Length(min=1, max=140)])
    submit = SubmitField('Submit')

# 10.4  Reset password request form.
class ResetPasswordRequestForm(FlaskForm):
    email = StringField('Email', validators=[DataRequired(), Email()])
    submit = SubmitField('Request Password Reset')

# 10.7 password reset form
class ResetPasswordForm(FlaskForm):
    password = PasswordField('Password', validators=[DataRequired()])
    password2 = PasswordField(
        'Repeat Password', validators=[DataRequired(), EqualTo('password')])
    submit = SubmitField('Request Password Reset')

